/**
 * @file six_axis_sensor_can_sdk_simple.h
 * @brief STM32G431六维力传感器CAN总线C++ SDK (简化版)
 * @version 1.0.0
 * @date 2025-01-14
 * 
 * 支持功能：
 * - CAN-FD总线通信协议
 * - 读取软硬件版本号
 * - 读取固件编译时间  
 * - 读取SN码
 * - 解析0x65 FT数据包
 * - 实时6轴力/力矩数据读取
 * - 补偿功能控制
 * - 去皮功能控制
 */

#ifndef SIX_AXIS_SENSOR_CAN_SDK_H
#define SIX_AXIS_SENSOR_CAN_SDK_H

#include <string>
#include <vector>
#include <memory>
#include <functional>
#include <chrono>
#include <cstdint>

namespace SixAxisSensorCAN {

/**
 * @brief CAN帧类型枚举
 */
enum class CANFrameType {
    STANDARD = 0,    ///< 标准帧
    EXTENDED = 1     ///< 扩展帧
};

/**
 * @brief CAN帧结构体
 */
struct CANFrame {
    uint32_t id;                    ///< CAN ID
    CANFrameType frame_type;        ///< 帧类型
    uint8_t data[64];              ///< 数据域 (CAN-FD最大64字节)
    uint8_t data_length;           ///< 数据长度
    std::chrono::system_clock::time_point timestamp; ///< 时间戳
};

/**
 * @brief 6轴力/力矩数据结构
 */
struct ForceData {
    float fx;  ///< X方向力 (Kg)
    float fy;  ///< Y方向力 (Kg)
    float fz;  ///< Z方向力 (Kg)
    float tx;  ///< X方向力矩 (Kg·m)
    float ty;  ///< Y方向力矩 (Kg·m)
    float tz;  ///< Z方向力矩 (Kg·m)
    
    std::chrono::system_clock::time_point timestamp;  ///< 数据时间戳
    
    /**
     * @brief 转换为字符串
     */
    std::string toString() const;
};

/**
 * @brief 传感器状态枚举
 */
enum class SensorStatus {
    DISCONNECTED = 0,    ///< 未连接
    CONNECTED = 1,       ///< 已连接
    ERROR = 2            ///< 错误状态
};


/**
 * @brief 错误码枚举
 */
enum class ErrorCode {
    SUCCESS = 0,                ///< 成功
    CAN_INIT_FAILED = 1,       ///< CAN初始化失败
    CAN_SEND_FAILED = 2,       ///< CAN发送失败
    CAN_RECEIVE_TIMEOUT = 3,    ///< CAN接收超时
    INVALID_DATA = 4,           ///< 无效数据
    DEVICE_NOT_FOUND = 5,       ///< 设备未找到
    PROTOCOL_ERROR = 6,         ///< 协议错误
    INVALID_PARAMETER = 7,      ///< 无效参数
    UNSUPPORTED = 8,            ///< 不支持的操作
    COMMUNICATION_FAILED = 9    ///< 通信失败
};

/**
 * @brief 数据回调函数类型
 */
using DataCallback = std::function<void(const ForceData& data)>;

/**
 * @brief 错误回调函数类型
 */
using ErrorCallback = std::function<void(ErrorCode error, const std::string& message)>;

/**
 * @brief CAN帧回调函数类型
 */
using CANFrameCallback = std::function<void(const CANFrame& frame)>;

/**
 * @brief 六维力传感器CAN SDK主类
 */
class SixAxisSensorCANSDK {
public:
    /**
     * @brief 构造函数
     */
    SixAxisSensorCANSDK();
    
    /**
     * @brief 析构函数
     */
    ~SixAxisSensorCANSDK();
    
    // 禁用拷贝构造和拷贝赋值
    SixAxisSensorCANSDK(const SixAxisSensorCANSDK&) = delete;
    SixAxisSensorCANSDK& operator=(const SixAxisSensorCANSDK&) = delete;
    
    /**
     * @brief 扫描可用CAN接口
     * @return 可用CAN接口列表
     */
    std::vector<std::string> scanCANInterfaces();
    
    /**
     * @brief 初始化CAN接口
     * @param interface_name CAN接口名称 (如 "can1", "vcan0")
     * @param arbitration_bitrate 仲裁域位速率，默认1Mbps
     * @param data_bitrate 数据域位速率，默认1Mbps
     * @param fd_mode 是否启用CAN-FD模式，默认true
     * @param sensor_id 传感器ID，默认0x64，数据ID会自动设为sensor_id+1
     * @return 错误码
     */
    ErrorCode initCAN(const std::string& interface_name, 
                     uint32_t arbitration_bitrate = 1000000,
                     uint32_t data_bitrate = 1000000,
                     bool fd_mode = true,
                     uint32_t sensor_id = 0x64);
    
    /**
     * @brief 关闭CAN接口
     */
    void closeCAN();
    
    /**
     * @brief 获取连接状态
     * @return 传感器状态
     */
    SensorStatus getStatus() const;
    
    /**
     * @brief 获取当前配置的传感器ID
     * @return 传感器ID
     */
    uint32_t getSensorID() const;
    
    /**
     * @brief 获取数据ID (传感器ID + 1)
     * @return 数据ID
     */
    uint32_t getDataID() const;
    
    /**
     * @brief 读取软硬件版本号
     * @param[out] hardware_version 硬件版本号
     * @param[out] software_version 软件版本号
     * @return 错误码
     */
    ErrorCode getVersion(uint16_t& hardware_version, uint16_t& software_version);
    
    /**
     * @brief 获取完整版本字符串
     * @param[out] version_string 完整版本字符串
     * @return 错误码
     */
    ErrorCode getFullVersionString(std::string& version_string);
    
    /**
     * @brief 获取详细版本信息
     * @param[out] hw_version 硬件版本字符串 (如 "0.0.0.4")
     * @param[out] sw_version 软件版本字符串 (如 "2.0.2.7")
     * @return 错误码
     */
    ErrorCode getDetailedVersionStrings(std::string& hw_version, std::string& sw_version);
    
    /**
     * @brief 读取固件编译时间
     * @param[out] build_time 固件编译时间字符串
     * @return 错误码
     */
    ErrorCode getFirmwareBuildTime(std::string& build_time);
    
    /**
     * @brief 读取SN序列号
     * @param[out] serial_number SN序列号字符串
     * @return 错误码
     */
    ErrorCode getSerialNumber(std::string& serial_number);
    
    
    /**
     * @brief 解析FT数据包(传感器ID+1格式)
     * @param frame CAN帧数据
     * @param[out] data 解析后的力/力矩数据
     * @return 错误码
     */
    ErrorCode parseFTData(const CANFrame& frame, ForceData& data);
    
    /**
     * @brief 设置去皮功能
     * @param enable true为开启，false为关闭
     * @return 错误码
     */
    ErrorCode setTareFunction(bool enable);
    
    /**
     * @brief 修改传感器CAN ID
     * @param new_sensor_id 新的传感器ID
     * @return 错误码
     */
    ErrorCode changeSensorID(uint32_t new_sensor_id);
    
    /**
     * @brief 保存参数到flash
     * @return 错误码
     */
    ErrorCode saveParametersToFlash();
    
    /**
     * @brief 设置CAN帧监听回调
     * @param callback CAN帧回调函数
     */
    void setCANFrameCallback(CANFrameCallback callback);
    
    /**
     * @brief 启动CAN帧监听
     * @return 错误码
     */
    ErrorCode startCANListener();
    
    /**
     * @brief 停止CAN帧监听
     */
    void stopCANListener();
    
    /**
     * @brief 设置错误回调函数
     * @param callback 错误回调函数
     */
    void setErrorCallback(ErrorCallback callback);
    
    /**
     * @brief 设置调试模式
     * @param enable true为开启调试输出，false为关闭
     */
    void setDebugMode(bool enable);
    
    /**
     * @brief 获取SDK版本信息
     * @return SDK版本字符串
     */
    static std::string getSDKVersion();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;  ///< PIMPL idiom
};

} // namespace SixAxisSensorCAN

#endif // SIX_AXIS_SENSOR_CAN_SDK_H